package com.niiwoo.civet.account.service.local.openAccount;

import com.niiwoo.civet.account.dao.entity.*;
import com.niiwoo.civet.account.dto.request.CreateRegisterOrderRequestDTO;
import com.niiwoo.civet.account.dto.request.UpdateActivateAccountRequestDTO;
import com.niiwoo.civet.account.dto.request.UpdateGroupAccountCorrelateRequestDTO;
import com.niiwoo.civet.account.dto.request.UpdateRegisterOrderRequestDTO;
import com.niiwoo.civet.account.enums.AccountActiveEnum;
import com.niiwoo.civet.account.enums.AccountTypeEnum;
import com.niiwoo.civet.account.enums.ActivateAccountOrderStatusEnum;
import com.niiwoo.civet.account.enums.GroupAccountRelevant;
import com.niiwoo.civet.account.enums.OpenAccountOrderStatusEnum;
import com.niiwoo.civet.account.enums.OpenAccountRecordStatusEnum;
import com.niiwoo.tripod.lanmao.enums.AuthenticateValidTypeEnum;
import com.niiwoo.tripod.lanmao.enums.CredentialsTypeEnum;
import com.niiwoo.tripod.lanmao.enums.GroupAccountCorrelateTypeEnum;
import com.niiwoo.tripod.lanmao.enums.UserAuthorizationEnum;
import com.niiwoo.tripod.lanmao.enums.UserLimitTypeEnum;
import java.util.Date;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;

public class AccountEntityBuilder {

    static OpenAccountOrder buildUpdateOpenAccountOrder(boolean success, OpenAccountOrder order, UpdateRegisterOrderRequestDTO requestDTO) {
        OpenAccountOrder updateOrder = new OpenAccountOrder();
        updateOrder.setId(order.getId());
        updateOrder.setCheckType(requestDTO.getAccessType().getValue());
        updateOrder.setBankCode(requestDTO.getBankCode().getCode());
        updateOrder.setStatus(success ? OpenAccountOrderStatusEnum.SUCCESS.getValue() : OpenAccountOrderStatusEnum.FAILURE.getValue());
        updateOrder.setErrorCode(requestDTO.getErrorCode());
        updateOrder.setErrorMessage(requestDTO.getErrorMessage());
        return updateOrder;
    }

    static GroupAccountCorrelateOrder buildUpdateGroupAccountCorrelateOrder(boolean success, GroupAccountCorrelateOrder oldOrder, UpdateGroupAccountCorrelateRequestDTO requestDTO) {
        GroupAccountCorrelateOrder updateOrder = new GroupAccountCorrelateOrder();
        updateOrder.setId(oldOrder.getId());
        updateOrder.setStatus(success ? OpenAccountOrderStatusEnum.SUCCESS.getValue() : OpenAccountOrderStatusEnum.FAILURE.getValue());
        updateOrder.setErrorCode(requestDTO.getErrorCode());
        updateOrder.setErrorMessage(requestDTO.getErrorMessage());
        return updateOrder;
    }

    static ActivateAccountOrder buildUpdateActivateAccountOrder(ActivateAccountOrder order, ActivateAccountOrderStatusEnum status, UpdateActivateAccountRequestDTO requestDTO, Function<String, String> f) {
        ActivateAccountOrder updateOrder = new ActivateAccountOrder();
        updateOrder.setId(order.getId());
        updateOrder.setCheckType(requestDTO.getAccessType().getValue());
        updateOrder.setBankCardNo(f.apply(requestDTO.getBankCardNo()));
        updateOrder.setBankCode(requestDTO.getBankCode().getCode());
        updateOrder.setBankCardMobileNo(f.apply(requestDTO.getBankCardMobileNo()));
        updateOrder.setErrorCode(requestDTO.getErrorCode());
        updateOrder.setErrorMessage(requestDTO.getErrorMessage());
        updateOrder.setStatus(status.getValue());
        return updateOrder;
    }

    static OpenAccountRecord buildUpdateOpenAccountRecord(OpenAccountRecordStatusEnum recordStatus, OpenAccountRecord record, String groupAccountNo) {
        OpenAccountRecord updateRecord = new OpenAccountRecord();
        updateRecord.setId(record.getId());
        if (recordStatus == OpenAccountRecordStatusEnum.SUCCESS) {
            updateRecord.setGroupAccountNo(groupAccountNo);
            updateRecord.setStatus(OpenAccountRecordStatusEnum.SUCCESS.getValue());
            updateRecord.setSuccessTime(new Date());
        } else {
            updateRecord.setStatus(recordStatus.getValue());
        }
        return updateRecord;
    }

    /**
     * 获取更新或初始化开户记录
     *
     * @param openAccountRecordOpt 开户记录
     * @param groupAccountNo 集团账户编号
     */
    static OpenAccountRecord buildRefreshOpenAccountRecord(Optional<OpenAccountRecord> openAccountRecordOpt, Supplier<Long> s1, Supplier<String> s2, String groupAccountNo, CreateRegisterOrderRequestDTO requestDTO) {
        OpenAccountRecord record = new OpenAccountRecord();
        record.setLastRequestTime(new Date());
        record.setStatus(OpenAccountRecordStatusEnum.PROCESSING.getValue());
        record.setOpenAccountWay(requestDTO.getOpenAccountWay().getValue());
        if (openAccountRecordOpt.isPresent()) {
            // 存在则刷新状态和最后请求时间
            record.setId(openAccountRecordOpt.get().getId());
        } else {
            // 不存在则初始化记录
            record.setId(s1.get());
            record.setUserId(requestDTO.getUserId());
            record.setAccountNo(s2.get());
            // 集团账户关联方式传入集团账户编号
            record.setGroupAccountNo(groupAccountNo);
            record.setAccountRole(Integer.valueOf(requestDTO.getAccountRole().getValue()).byteValue());
            record.setCreateTime(new Date());
        }
        return record;
    }

    static OpenAccountOrder buildInitOpenAccountOrder(long id, String requestNo, OpenAccountRecord record, CreateRegisterOrderRequestDTO requestDTO, Function<String, String> s, String authList) {
        // 创建开户订单
        OpenAccountOrder order = new OpenAccountOrder();
        order.setId(id);
        order.setRequestNo(requestNo);
        order.setAccountNo(record.getAccountNo());
        order.setUserId(record.getUserId());
        order.setUserRole(record.getAccountRole());
        order.setRealName(requestDTO.getName());
        order.setCertNo(s.apply(requestDTO.getIdCardNo()));
        order.setCertType(Integer.valueOf(CredentialsTypeEnum.PRC_ID.getValue()).byteValue());
        order.setBindCardNo(s.apply(requestDTO.getBankCardNo()));
        order.setMobileNo(s.apply(requestDTO.getBankCardMobileNo()));
        order.setCheckType(Integer.valueOf(AuthenticateValidTypeEnum.LIMIT.getValue()).byteValue());
        order.setUserLimitType(Integer.valueOf(UserLimitTypeEnum.ID_CARD_NO_UNIQUE.getValue()).byteValue());
        order.setAuthList(authList);
        order.setStatus(OpenAccountOrderStatusEnum.PROCESSING.getValue());
        order.setIsRelevantGroupAccount(GroupAccountRelevant.YES.getValue());// 默认开通集团账户
        order.setCreateTime(new Date());
        return order;
    }


    static GroupAccountCorrelateOrder buildInitGroupAccountCorrelateOrder(long id, String requestNo, String accountNo, String groupAccountNO, CreateRegisterOrderRequestDTO requestDTO, String authList) {
        GroupAccountCorrelateOrder order = new GroupAccountCorrelateOrder();
        order.setId(id);
        order.setRequestNo(requestNo);
        order.setAccountNo(accountNo);
        order.setUserId(requestDTO.getUserId());
        order.setGroupAccountNo(groupAccountNO);
        order.setUserRole(Integer.valueOf(requestDTO.getAccountRole().getValue()).byteValue());
        order.setCorrelateType(Integer.valueOf(GroupAccountCorrelateTypeEnum.REGISTER_AUTH.getValue()).byteValue());
        order.setAuthList(authList);
        order.setStatus(OpenAccountOrderStatusEnum.PROCESSING.getValue());
        order.setCreateTime(new Date());
        return order;
    }

    /**
     * 创建账号基础信息
     *
     * @param record 开户记录
     */
    static AccountBase buildInitAccountBase(long id, OpenAccountRecord record, AccountTypeEnum accountType, Set<String> authSet) {
        AccountBase accountBase = new AccountBase();
        accountBase.setId(id);
        accountBase.setUserId(record.getUserId());
        accountBase.setAccountNo(record.getAccountNo());
        accountBase.setAccountRole(record.getAccountRole());
        accountBase.setCreateTime(new Date());
        accountBase.setImportUserActiva(AccountActiveEnum.ACTIVATED.getValue());
        accountBase.setTender((byte)(authSet.contains(UserAuthorizationEnum.TENDER.name()) ? 1 : 0));
        accountBase.setRepayment((byte)(authSet.contains(UserAuthorizationEnum.REPAYMENT.name()) ? 1 : 0));
        accountBase.setCreditAssignment((byte)(authSet.contains(UserAuthorizationEnum.CREDIT_ASSIGNMENT.name()) ? 1 : 0));
        accountBase.setCompensatory((byte)(authSet.contains(UserAuthorizationEnum.COMPENSATORY.name()) ? 1 : 0));
        accountBase.setWithdraw((byte)(authSet.contains(UserAuthorizationEnum.WITHDRAW.name()) ? 1 : 0));
        accountBase.setRecharge((byte)(authSet.contains(UserAuthorizationEnum.RECHARGE.name()) ? 1 : 0));
        accountBase.setAccountType(Integer.valueOf(accountType.getValue()).byteValue());
        return accountBase;
    }

    /**
     * 创建账号个人信息
     *
     * @param record 开户记录
     * @param accountBase 账号基础信息
     * @param realName 真实姓名
     * @param certNo 加密的身份证号码
     * @param certType 证件类型
     */
    static AccountPerson buildInitAccountPerson(OpenAccountRecord record, AccountBase accountBase, String realName, String certNo, CredentialsTypeEnum certType) {
        AccountPerson accountPerson = new AccountPerson();
        accountPerson.setAccountId(accountBase.getId());
        accountPerson.setAccountNo(record.getAccountNo());
        accountPerson.setUserId(record.getUserId());
        accountPerson.setRealName(realName);
        accountPerson.setIdCard(certNo);
        accountPerson.setIdCardType(Integer.valueOf(certType.getValue()).byteValue());
        accountPerson.setCreateTime(new Date());
        return accountPerson;
    }


    /**
     * 创建银行卡记录
     */
    static BankCard buildInitBankCard(long id, long bankCardTypeId, String userId, Long accountId, byte accountType, String name, String idCardNo, String bankCardNo, String bankCode, String bankCardMobileNo) {
        BankCard bankCard = new BankCard();
        bankCard.setId(id);
        bankCard.setUserId(userId);
        if (accountType == AccountTypeEnum.ENTERPRISE.getValue()) {
            bankCard.setAccountId(accountId);
        }
        bankCard.setAccountType(accountType);
        bankCard.setBankTypeId(bankCardTypeId);
        bankCard.setBankCode(bankCode);
        bankCard.setBankAccountNo(bankCardNo);
        bankCard.setRealName(name);
        bankCard.setIdCard(idCardNo);
        bankCard.setMobileNo(bankCardMobileNo);
        bankCard.setCreateTime(new Date());
        return bankCard;
    }


    static AccountBase buildActivateAccountBase(AccountBase oldBase, Set<String> authSet) {
        AccountBase updateBase = new AccountBase();
        updateBase.setId(oldBase.getId());
        updateBase.setImportUserActiva(AccountActiveEnum.ACTIVATED.getValue());
        updateBase.setUpdateTime(new Date());
        updateBase.setTender((byte)(authSet.contains(UserAuthorizationEnum.TENDER.name()) ? 1 : 0));
        updateBase.setRepayment((byte)(authSet.contains(UserAuthorizationEnum.REPAYMENT.name()) ? 1 : 0));
        updateBase.setCreditAssignment((byte)(authSet.contains(UserAuthorizationEnum.CREDIT_ASSIGNMENT.name()) ? 1 : 0));
        updateBase.setCompensatory((byte)(authSet.contains(UserAuthorizationEnum.COMPENSATORY.name()) ? 1 : 0));
        updateBase.setWithdraw((byte)(authSet.contains(UserAuthorizationEnum.WITHDRAW.name()) ? 1 : 0));
        updateBase.setRecharge((byte)(authSet.contains(UserAuthorizationEnum.RECHARGE.name()) ? 1 : 0));
        return updateBase;
    }

    static AccountPerson buildActivateAccountPerson(long accountId, String name, String idCardNo) {
        AccountPerson accountPerson = new AccountPerson();
        accountPerson.setAccountId(accountId);
        accountPerson.setAuditStatus((byte) 1);
        accountPerson.setUpdateTime(new Date());
        accountPerson.setRealName(name);
        accountPerson.setIdCard(idCardNo);
        return accountPerson;
    }


    static BankCard buildUpdateBankCard(BankCard oldCard, String bankCardNo, long bankCardTypeId, String bankCode, String bankCardMobileNo, String name, String idCardNo) {
        BankCard bankCard = new BankCard();
        bankCard.setId(oldCard.getId());
        bankCard.setBankTypeId(bankCardTypeId);
        bankCard.setBankCode(bankCode);
        bankCard.setBankAccountNo(bankCardNo);
        bankCard.setMobileNo(bankCardMobileNo);
        bankCard.setUpdateTime(new Date());
        bankCard.setRealName(name);
        bankCard.setIdCard(idCardNo);
        return bankCard;
    }

    static ActivateAccountOrder buildInitActivateAccountOrder(long id, String requestNo, AccountBase accountBase, String authList) {
        ActivateAccountOrder order = new ActivateAccountOrder();
        order.setId(id);
        order.setRequestNo(requestNo);
        order.setAccountNo(accountBase.getAccountNo());
        order.setUserId(accountBase.getUserId());
        order.setUserRole(Integer.valueOf(accountBase.getAccountRole()).byteValue());
        order.setCheckType(Integer.valueOf(AuthenticateValidTypeEnum.LIMIT.getValue()).byteValue());
        order.setAuthList(authList);
        order.setStatus(ActivateAccountOrderStatusEnum.PROCESSING.getValue());
        order.setCreateTime(new Date());
        return order;
    }

    static AccountCompany buildActivateAccountCompany(Long accountId, String companyName, String legalPersonName, String legalPersonIdCard, CredentialsTypeEnum idCardTyp, String contactMobileNo, String bankLicence) {
        AccountCompany company = new AccountCompany();
        company.setAccountId(accountId);
        company.setAuditStatus((byte) 1);
        company.setUpdateTime(new Date());
        company.setCompanyName(companyName);
        company.setLegalPersonName(legalPersonName);
        company.setLegalPersonIdCard(legalPersonIdCard);
        company.setIdCardType(idCardTyp.getValue());
        company.setContactMobileNo(contactMobileNo);
        company.setBankLicence(bankLicence);
        return company;
    }

}